package com.k12.user.interceptor;

import com.k12.user.model.annotation.SensitiveField;
import com.k12.user.util.AesUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import java.lang.reflect.Field;
import java.sql.Statement;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;

@Intercepts({
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
        @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class SensitiveDataInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 处理update操作(insert/update)
        if (invocation.getTarget() instanceof Executor) {
            Object parameter = invocation.getArgs()[1];
            if (parameter != null) {
                encryptFields(parameter);
            }
        }
        // 处理select操作
        else if (invocation.getTarget() instanceof ResultSetHandler) {
            Object result = invocation.proceed();
            if (result instanceof Collection) {
                for (Object obj : (Collection<?>) result) {
                    decryptFields(obj);
                }
            } else if (result != null) {
                decryptFields(result);
            }
            return result;
        }
        return invocation.proceed();
    }

    private void encryptFields(Object parameter) {
        if (parameter instanceof Map<?, ?> paramMap) {
            // 处理Map参数
            for (Object value : paramMap.values()) {
                processFields(value);
            }
        } else {
            // 处理实体对象参数
            processFields(parameter);
        }
    }

    private void decryptFields(Object result) {
        processFields(result);
    }

    private void processFields(Object object) {
        if (object == null) return;

        Class<?> clazz = object.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            if (field.isAnnotationPresent(SensitiveField.class)) {
                try {
                    field.setAccessible(true);
                    Object value = field.get(object);
                    if (value instanceof String strValue) {
                        if (!strValue.isEmpty()) {
                            String processedValue = AesUtils.deterministicEncrypt(strValue);
                            field.set(object, processedValue);
                        }
                    }
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("处理敏感字段失败", e);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        System.out.println("SensitiveDataInterceptor.setProperties");
        // 可以在这里读取配置
    }
}